package models

import (
	"errors"
	"fmt"
	"github.com/beego/beego/v2/client/orm"
	"strconv"
)

type ErpProductsPrice struct {
	Id                   int64           `json:"id"`
	Products             *ErpProducts    `orm:"rel(fk);null;on_delete(do_nothing)" json:"-"`
	Department           *Department     `orm:"rel(fk);null;on_delete(do_nothing)" json:"department"`
	Snd                  *ErpProductsSnd `orm:"rel(fk);null;on_delete(do_nothing)" json:"snd"`
	SphMin               float64         `json:"sph_min"`
	SphMax               float64         `json:"sph_max"`
	CylMin               float64         `json:"cyl_min"`
	CylMax               float64         `json:"cyl_max"`
	SuggestedPrice       float64         `json:"suggested_price"`
	TradePrice           float64         `json:"trade_price"`
	CustomSuggestedPrice float64         `json:"custom_suggested_price"`
	CustomTradePrice     float64         `json:"custom_trade_price"`
	IsPublic             int             `json:"is_public"`
}

func (a *ErpProductsPrice) TableName() string {
	return ErpProductsPriceTableName()
}

func ErpProductsPriceTableName() string {
	return TableName("erp_products_price")
}

//查询
type ErpProductsPriceQueryParam struct {
	BaseQueryParam
	Products   int64 `json:"product_id"`
	Department int64 `json:"department"`
}

func ErpProductsPricePageList(params *ErpProductsPriceQueryParam) ([]*ErpProductsPrice, int64) {
	ls := make([]*ErpProductsPrice, 0)
	query := orm.NewOrm().QueryTable(ErpProductsPriceTableName()).RelatedSel("Department", "Snd")
	cond := orm.NewCondition()

	if params.Products > 0 {
		cond = cond.And("Products__Id", params.Products)
	}
	if params.Department > 0 {
		cond = cond.And("Department__Id", params.Department)
	}
	query = query.SetCond(cond)
	sortorder := "-Id"
	switch params.Sort {
	case "Id":
		sortorder = "Id"
	}
	if params.Order == "desc" {
		sortorder = "-" + sortorder
	}
	var order []string
	order = append(order, "-IsPublic")
	order = append(order, sortorder)
	total, _ := query.Count()
	query.OrderBy(order...).Limit(params.Limit, params.Offset).All(&ls)
	return ls, total
}

//新增产品价格
func ErpProductsPriceAdd(data *ErpProductsPrice) error {
	to, _ := orm.NewOrm().Begin()
	var count_id int64
	if data.Products.TypeId == 10 || data.Products.TypeId == 20 || data.Products.TypeId == 40 { //存在球镜则验证是否存在区间
		where := fmt.Sprintf(" AND ((sph_min >= %f AND sph_min <= %f) OR (sph_min <= %f AND sph_max >= %f) OR (sph_max >= %f AND sph_max <= %f))", data.SphMin, data.SphMax, data.SphMin, data.SphMax, data.SphMin, data.SphMax)
		to.Raw("SELECT id FROM "+ErpProductsPriceTableName()+" WHERE snd_id=0 AND products_id=? AND department_id=?"+where, data.Products.Id, data.Department.Id).QueryRow(&count_id)
		if count_id > 0 {
			return errors.New("球镜区间范围定价重复，请核实价格信息。")
		}
	} else {
		to.Raw("SELECT id FROM "+ErpProductsPriceTableName()+" WHERE products_id=? AND department_id=? AND snd_id=?", data.Products.Id, data.Department.Id, data.Snd.Id).QueryRow(&count_id)
		if count_id > 0 {
			return errors.New("定价重复，请核实价格信息。")
		}
	}
	if data.Products.Id == 0 {
		return errors.New("商品信息不正确")
	}

	if _, err := to.Insert(data); err != nil {
		to.Rollback()
		return err
	}
	//更新SND价格
	data.Snd.SuggestedPrice = data.SuggestedPrice
	data.Snd.TradePrice = data.TradePrice
	if _, err := to.Update(data.Snd, "SuggestedPrice", "TradePrice"); err != nil {
		to.Rollback()
		return err
	}
	to.Commit()
	return nil
}

//编辑
func ErpProductsPriceSave(data *ErpProductsPrice) error {
	to, _ := orm.NewOrm().Begin()
	if data.Id == 0 { //新增
		return errors.New("参数错误")
	}
	//如果该项被设置为公共则取消其它公共价格
	if data.IsPublic == 1 {
		if data.Department.Id == 0 || data.Products.Id == 0 {
			return errors.New("缺少部门或产品信息")
		}
		if _, err := to.QueryTable(ErpProductsPriceTableName()).Filter("department_id", data.Department.Id).Filter("products_id", data.Products.Id).Update(orm.Params{"is_public": 0}); err != nil {
			to.Rollback()
			return err
		}
	}
	//更新指定表
	if _, err := to.Update(data, "suggested_price", "trade_price", "CustomSuggestedPrice", "CustomTradePrice", "IsPublic"); err != nil {
		to.Rollback()
		return err
	}
	//更新SND价格
	data.Snd.SuggestedPrice = data.SuggestedPrice
	data.Snd.TradePrice = data.TradePrice
	if _, err := to.Update(data.Snd, "SuggestedPrice", "TradePrice"); err != nil {
		to.Rollback()
		return err
	}
	to.Commit()
	return nil
}

//程序自动生成
func ErpProductsPriceAutoSave(o orm.TxOrmer, price *ErpProductsPrice) (*ErpProductsPrice, error) {
	o.QueryTable(ErpProductsPriceTableName()).Filter("department_id", price.Department.Id).Filter("products_id", price.Products.Id).Filter("snd_id", price.Snd.Id).One(price)
	if price.Id == 0 {
		if _, err := o.Insert(price); err != nil {
			return price, err
		}
	}
	return price, nil
}

//获取单条数据
func GetErpProductsPriceById(id int64) *ErpProductsPrice {
	price := new(ErpProductsPrice)
	orm.NewOrm().QueryTable(ErpProductsPriceTableName()).RelatedSel("Department", "Products", "Snd").Filter("id", id).One(price)
	return price
}

//获取产品价格
func GetErpProductsPriceByIdAndDep(depid int64, product_id int64) *ErpProductsPrice {
	price := new(ErpProductsPrice)
	orm.NewOrm().QueryTable(ErpProductsPriceTableName()).Filter("department_id", depid).Filter("products_id", product_id).One(price)
	return price
}

//删除价格
func DeleteErpProductsPriceById(id int64) error {
	price := new(ErpProductsPrice)
	price.Id = id
	if _, err := orm.NewOrm().Delete(price); err != nil {
		return err
	}
	return nil
}

//获取未设置价格的SND记录
func GetSndNosetPrice(params *ErpProductsSndQueryParam) ([]*ErpProductsSnd, int64) {

	ls := make([]*ErpProductsSnd, 0)
	query := orm.NewOrm().QueryTable(ErpProductsSndTableName())
	cond := orm.NewCondition()
	cond = cond.And("Products__Id", params.Products)
	cond1 := orm.NewCondition()
	cond = cond.AndCond(cond1.Raw("id", "NOT IN(SELECT snd_id FROM "+ErpProductsPriceTableName()+" T2 WHERE T2.products_id="+strconv.FormatInt(params.Products, 10)+" AND department_id="+strconv.FormatInt(params.Department, 10)+")"))
	query = query.SetCond(cond)
	sortorder := "-Id"
	switch params.Sort {
	case "Id":
		sortorder = "Id"
	}
	if params.Order == "desc" {
		sortorder = "-" + sortorder
	}
	total, _ := query.Count()
	query.OrderBy(sortorder).Limit(params.Limit, params.Offset).All(&ls)
	return ls, total
}

//按条件获取价格
type InventoryPriceQueryParams struct {
	DepId   int64
	Sph     string          //球镜
	Cyl     string          //柱镜
	Add     string          //下加光
	Snd     *ErpProductsSnd //SND ID
	Product *ErpProducts    //产品ID
	Public  string          //公共价格
}

func GetInventoryPriceForQueryParams(params *InventoryPriceQueryParams) *ErpProductsPrice {
	price := new(ErpProductsPrice)
	query := orm.NewOrm().QueryTable(ErpProductsPriceTableName())
	query = query.Filter("products_id", params.Product.Id)
	query = query.Filter("department_id", params.DepId)
	if len(params.Public) > 0 {
		query = query.Filter("is_public", params.Public)
		query.One(price)
		return price
	} else {
		if params.Product.TypeId == 10 || params.Product.TypeId == 20 || params.Product.TypeId == 40 {
			sph, _ := strconv.ParseFloat(params.Sph, 64)
			query = query.Filter("sph_max__gte", sph).Filter("sph_min__lte", sph)
		} else {
			query = query.Filter("snd_id", params.Snd.Id)
		}
	}
	query.One(price)
	//如果找不到价格，再查询是否有公共价格
	if price.Id == 0 {
		params.Public = "1"
		price = GetInventoryPriceForQueryParams(params)
	}
	return price
}
